<template>
  <div class="app-container">
    <div class="filter-container">
      <el-button
        type="primary"
        @click="toAdd"
      ><i class="el-icon-plus" />添加菜单</el-button>
    </div>
    <el-table
      :data="menuListData"
      style="width: 100%"
      row-key="id"
      border
      lazy
      :load="loadChildren"
      :tree-props="{ children: 'children', hasChildren: 'hasChildren' }"
    >
      <el-table-column prop="name" label="菜单名称" width="180" />
      <el-table-column prop="icon" label="菜单图标" width="180">
        <template slot-scope="scope">
          <i :class="scope.row.icon" />
        </template>
      </el-table-column>
      <el-table-column prop="path" label="菜单路径" width="180" />
      <el-table-column prop="code" label="菜单编码" width="180" />
      <el-table-column prop="component" label="组件路径" width="180" />
      <el-table-column label="操作">
        <template slot-scope="scope">
          <el-button type="warning" @click="modifyMenu(scope.row.id)">修改</el-button>
          <el-button type="danger" @click="removeMenu(scope.row.id)">删除</el-button>
        </template>
      </el-table-column>
    </el-table>
    <el-dialog
      :title="dialogType === 'Add' ? '新增菜单' : '修改菜单'"
      :visible.sync="dialogFormVisible"
      width="800px"
    >
      <el-form ref="menuForm" :model="formData" :rules="rules" label-width="100px">
        <el-row>
          <el-col :span="24">
            <treeselect
              v-model="formData.parentId"
              :options="options"
              :load-options="loadOptions"
              :normalizer="treeSelectProp"
            />
          </el-col>
        </el-row>
        <el-row>
          <el-col :span="12">
            <el-form-item label="菜单名称" prop="name">
              <el-input v-model="formData.name" type="text" />
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="菜单路径" prop="path">
              <el-input v-model="formData.path" type="text" />
            </el-form-item>
          </el-col>
        </el-row>
        <el-row>
          <el-col :span="12">
            <el-form-item label="菜单编码" prop="code">
              <el-input v-model="formData.code" type="text" />
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="组件路径" prop="component">
              <el-input v-model="formData.component" type="text" />
            </el-form-item>
          </el-col>
        </el-row>
        <el-row>
          <el-col :span="12">
            <el-form-item label="是否隐藏" prop="hidden">
              <el-radio-group v-model="formData.hidden">
                <el-radio :label="false">显示</el-radio>
                <el-radio :label="true">隐藏</el-radio>
              </el-radio-group>
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="是否不缓存" prop="noCache">
              <el-radio-group v-model="formData.noCache">
                <el-radio :label="false">缓存</el-radio>
                <el-radio :label="true">不缓存</el-radio>
              </el-radio-group>
            </el-form-item>
          </el-col>
        </el-row>
        <el-row>
          <el-col :span="12">
            <el-form-item label="菜单图标" prop="icon">
              <el-input v-model="formData.icon" type="text" />
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="重写向地址" prop="redirect">
              <el-input v-model="formData.redirect" type="text" />
            </el-form-item>
          </el-col>
        </el-row>
        <el-row>
          <el-col :span="12">
            <el-form-item label="始终显示" prop="alwaysShow">
              <el-radio-group v-model="formData.alwaysShow">
                <el-radio :label="true">是</el-radio>
                <el-radio :label="false">否</el-radio>
              </el-radio-group>
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="激活菜单路径" prop="activeMenu">
              <el-input v-model="formData.activeMenu" type="text" />
            </el-form-item>
          </el-col>
        </el-row>
        <el-row>
          <el-col :span="12">
            <el-form-item label="排序" prop="sort">
              <el-input v-model="formData.sort" type="number" min="0" />
            </el-form-item>
          </el-col>
        </el-row>
        <el-row>
          <el-col :span="24">
            <el-form-item label="描述" prop="description">
              <el-input v-model="formData.description" type="textarea" />
            </el-form-item>
          </el-col>
        </el-row>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button @click="dialogFormVisible = false">取 消</el-button>
        <el-button type="primary" @click="saveMenu">确 定</el-button>
      </div>
    </el-dialog>
  </div>
</template>
<script>
import { menuTree, addMenu, deleteMenu, getMenuById, updateMenu } from '@/api/menu'
import { deepClone } from '@/utils'
import { getRepeatToken } from '@/api/global'
import { Treeselect, LOAD_CHILDREN_OPTIONS } from '@riophae/vue-treeselect'
import '@riophae/vue-treeselect/dist/vue-treeselect.css'
export default {
  name: 'MenuIndex',
  components: {
    Treeselect
  },
  data() {
    return {
      menuListData: [],
      options: [],
      formData: {
        id: '',
        name: '', // 菜单名称
        path: '', // 菜单路径
        children: [], // 子菜单
        code: '', // 菜单编码
        parentId: '-1', // 上级菜单ID
        sort: 0, // 排序
        hidden: false, // 是否为隐藏菜单
        component: '', // 组件路径(如无则固定为Layout)
        noCache: true, // 不缓存
        activeMenu: '', // 激活菜单路径
        description: '', // 描述
        redirect: '', // 重写向地址
        icon: '', // 图标
        ext01: '', // 扩展字段1
        ext02: '', // 扩展字段2
        alwaysShow: false, // 是否始终显示
        ext03: '' // 扩展字段3
      },
      dialogType: 'Add',
      dialogFormVisible: false,
      rules: {},
      temp: {},
      repeatToken: ''
    }
  },
  created() {
    this.temp = deepClone(this.formData)
    this.initData()
  },
  methods: {
    initData(id) {
      id = id || -1
      getRepeatToken().then((res) => {
        this.repeatToken = res.data.token
      })
      menuTree(id).then((res) => {
        this.menuListData = res.data.list
      })
    },
    loadChildren(row, treeNode, resolve) {
      menuTree(row.id).then((res) => {
        const arr = res.data.list
        arr.filter((v) => {
          v.hasChildren = false
        })
        resolve(arr)
      })
    },
    saveMenu() {
      this.$refs['menuForm'].validate((valid) => {
        if (valid) {
          if (this.dialogType == 'Add') {
            addMenu(this.formData, { token: this.repeatToken })
              .then((res) => {
                if (res.meta.code == 200) {
                  this.$message.success('操作成功!')
                  this.dialogFormVisible = false
                }
                this.initData()
              })
              .catch((err) => {
                this.initData()
              })
          } else {
            updateMenu(this.formData, { token: this.repeatToken })
              .then((res) => {
                if (res.meta.code == 200) {
                  this.$message.success('操作成功!')
                  this.dialogFormVisible = false
                }
                this.initData()
              })
              .catch((err) => {
                this.initData()
              })
          }
        } else {
          return false
        }
      })
    },
    getMenuTree() {
      menuTree(-1).then((res) => {
        this.options = res.data.list
      })
    },
    toAdd() {
      this.formData = deepClone(this.temp)
      this.getMenuTree()
      this.dialogType = 'Add'
      this.dialogFormVisible = true
    },
    removeMenu(id) {
      this.$confirm('此操作将永久删除该菜单, 是否继续?', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      })
        .then(() => {
          deleteMenu(id, { token: this.repeatToken }).then((res) => {
            if (res.meta.code == 200) {
              this.menuListData = []
              this.initData()

              this.$message({
                type: 'success',
                message: '删除成功!'
              })
            }
          })
        })
        .catch(() => {})
    },
    modifyMenu(id) {
      getMenuById(id).then((res) => {
        this.getMenuTree()
        this.formData = res.data.data
        this.dialogType = 'Mod'
        this.dialogFormVisible = true
      })
    },
    loadOptions({ action, parentNode, callback }) {
      if (action === LOAD_CHILDREN_OPTIONS) {
        menuTree(parentNode.id).then((res) => {
          res.data.list.filter((v) => {
            v.children = false
          })
          parentNode.children = res.data.list
          callback()
        })
      }
    },
    treeSelectProp(node) {
      if (node.id == '-1') {
        return {
          id: node.id,
          label: '顶级菜单',
          children: []
        }
      }
      return {
        id: node.id,
        label: node.name,
        children: node.children
      }
    }
  }
}
</script>
